package com.xbongbong.saas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.UnitItemPoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.businessdata.pojo.dto.ProductListDataDTO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.product.pojo.vo.SourceProductListVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.BusinessProductEntity;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.RefundEntityExt;
import com.xbongbong.saas.domain.entity.ext.TransferEntityExt;
import com.xbongbong.saas.enums.ContractProductTypeEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.enums.product.ContractOutstockProductEnum;
import com.xbongbong.saas.enums.product.InstockProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.PriceSetScopeEnum;
import com.xbongbong.saas.enums.product.PurchaseInstockProductEnum;
import com.xbongbong.saas.enums.product.RefundInstockProductEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.enums.product.ReturnPurchaseProductEnum;
import com.xbongbong.saas.enums.product.ReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.enums.product.TransferProductEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.InventoryProductModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.ProductionOrderProductModel;
import com.xbongbong.saas.model.PurchaseProductModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.ReturnedPurchaseProductModel;
import com.xbongbong.saas.model.TransferModel;
import com.xbongbong.saas.model.TransferProductModel;
import com.xbongbong.saas.model.WorkOrderProductModel;
import com.xbongbong.sys.domain.entity.PriceProductSetEntity;
import com.xbongbong.sys.domain.entity.PriceSetEntity;
import com.xbongbong.sys.model.PriceSetModel;
import org.apache.commons.collections4.MapUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Component
public class RelativeProductHelp {
    private static final Logger LOG = LoggerFactory.getLogger(RelativeProductHelp.class);
    
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private PurchaseProductModel purchaseProductModel;
    @Resource
    private InventoryProductModel inventoryProductModel;
    @Resource
    private RefundModel refundModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private ReturnedPurchaseProductModel returnedPurchaseProductModel;
    @Resource
    private WorkOrderProductModel workOrderProductModel;
    @Resource
    private TransferProductModel transferProductModel;
    @Resource
    private ProductionOrderProductModel productionOrderProductModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private TransferModel transferModel;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private InstockModel instockModel;
    @Resource
    private PriceSetModel priceSetModel;

    /**
     * 出库关联单据产品检索
     * @param corpid
     * @param refId
     * @param type
     * @param needMerge 是否需要合并
     * @return
     * @throws XbbException
     */
    public List<BusinessProductEntity> getOutstockRelyBusinessProduct(String corpid, Long refId, Integer type, boolean needMerge) throws XbbException {
        OutstockTypeEnum outstockTypeEnum = OutstockTypeEnum.getByCode(type);
        List<BusinessProductEntity> businessProductEntityList = new ArrayList<>();
        switch (outstockTypeEnum){
            case RETURNED_PURCHASE_OUTSTOCK:
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("returnPurchaseId",refId);
                param.put("del",0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = returnedPurchaseProductModel.findProductNum(param);
                if (needMerge) {
                    Map<Long,BusinessProductEntity> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (BusinessProductEntity entity : businessProductEntityList){
                        if (productMap.containsKey(entity.getProductId())){
                            BusinessProductEntity businessProductEntity = productMap.get(entity.getProductId());
                            Double preNum = businessProductEntity.getProductNum();
                            Double prePrice = businessProductEntity.getCost();
                            String preMemo = businessProductEntity.getMemo();
                            Double nowNum = entity.getProductNum();
                            Double nowPrice = entity.getCost();
                            String nowMemo = entity.getMemo();
                            Double price = (preNum * prePrice + nowNum * nowPrice) / (preNum + nowNum);
                            Double num = preNum + nowNum;
                            String memo = "";
                            if (!StringUtil.isEmpty(nowMemo)){
                                if (StringUtil.isEmpty(preMemo)){
                                    memo = nowMemo;
                                }else {
                                    memo = preMemo + "/" + nowMemo;
                                }
                            }
                            businessProductEntity.setProductNum(num);
                            businessProductEntity.setPrice(price);
                            businessProductEntity.setCost(price);
                            businessProductEntity.setMemo(memo);
                            productMap.put(entity.getProductId(),businessProductEntity);
                        }else {
                            productMap.put(entity.getProductId(),entity);
                        }
                    }
                    businessProductEntityList = new ArrayList<>(productMap.values());
                }
                break;
            case CONTRACT_OUTSTOCK:
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("contractId",refId);
                param.put("type", XbbRefTypeEnum.CONTRACT.getCode());
                param.put("del",0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = contractProductModel.findProductNum(param);
                if (needMerge) {
                    Map<Long,BusinessProductEntity> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (BusinessProductEntity entity : businessProductEntityList){
                        if (productMap.containsKey(entity.getProductId())){
                            BusinessProductEntity businessProductEntity = productMap.get(entity.getProductId());
                            Double preNum = businessProductEntity.getProductNum();
                            Double prePrice = businessProductEntity.getPrice();
                            Double preDiscount = businessProductEntity.getDiscount();
                            String preMemo = businessProductEntity.getMemo();
                            Double nowNum = entity.getProductNum();
                            Double nowPrice = entity.getPrice();
                            Double nowDiscount = entity.getDiscount();

                            String nowMemo = entity.getMemo();
                            Double price = (preNum * prePrice + nowNum * nowPrice) / (preNum + nowNum);
                            Double num = preNum + nowNum;
                            String memo = "";
                            Double discount = (preDiscount * preNum + nowDiscount * nowNum) / num;
                            if (!StringUtil.isEmpty(nowMemo)){
                                if (StringUtil.isEmpty(preMemo)){
                                    memo = nowMemo;
                                }else {
                                    memo = preMemo + "/" + nowMemo;
                                }
                            }
                            businessProductEntity.setProductNum(num);
                            businessProductEntity.setPrice(price);
                            businessProductEntity.setCost(price);
                            businessProductEntity.setMemo(memo);
                            businessProductEntity.setDiscount(discount);
                            productMap.put(entity.getProductId(),businessProductEntity);
                        }else {
                            productMap.put(entity.getProductId(),entity);
                        }
                    }
                    businessProductEntityList = new ArrayList<>(productMap.values());
                }
                break;
            case WORK_ORDER_OUTSTOCK:
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("workOrderId",refId);
                param.put("del",0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = new ArrayList<>(workOrderProductModel.findProductNum(param));
                break;
            case INVENTORY_OUTSTOCK:
                businessProductEntityList = new ArrayList<>(inventoryProductModel.getInventorySurplusNum(corpid,refId, false));
                for (BusinessProductEntity entity : businessProductEntityList){
                    entity.setGuaranteePeriod(Objects.isNull(entity.getGuaranteePeriod()) ? null : entity.getGuaranteePeriod() / 86400);
                    JSONObject data = entity.getData();
                    if (Objects.nonNull(data)) {
                        entity.setMemo(data.getString(TransferProductEnum.MEMO.getAttr()));
                        entity.setBatch(data.getString(TransferProductEnum.BATCH.getAttr()));
                        entity.setProduceDate(data.getLong(TransferProductEnum.PRODUCE_DATE.getAttr()));
                        entity.setGuaranteePeriod(data.getLong(TransferProductEnum.GUARANTEE_PERIOD.getAttr()));
                    }
                }
                break;
            case TRANSFER_OUTSTOCK:
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("transferId",refId);
                param.put("del",0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = new ArrayList<>(transferProductModel.findProductNum(param));
                for (BusinessProductEntity entity : businessProductEntityList){
                    if (Objects.nonNull(entity.getGuaranteePeriod())) {
                        entity.setGuaranteePeriod(entity.getGuaranteePeriod() / TimeConstant.SECONDS_PER_DAY);
                    }
                }
                break;
            case MATERIEL_OUTSTOCK:
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("productionOrderId",refId);
                param.put("del",0);
                param.put("type",2);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = new ArrayList<>(productionOrderProductModel.findProductNum(param));
                break;
            default:
                break;
        }
        return businessProductEntityList;
    }

    /**
     * 入库关联单据产品检索
     * @param corpid
     * @param refId
     * @param type
     * @param needMerge 是否需要合并
     * @return
     * @throws XbbException
     */
    public List<BusinessProductEntity> getInstockRelyBusinessProduct(String corpid, Long refId, Integer type, boolean needMerge) throws XbbException {
        InstockTypeEnum instockTypeEnum = InstockTypeEnum.getByCode(type);
        List<BusinessProductEntity> businessProductEntityList = new ArrayList<>();
        switch (instockTypeEnum){
            case PURCHASE_INSTOCK:
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("purchaseSheetId", refId);
                param.put("del", 0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                //拿到采购合同的所有产品
                businessProductEntityList = purchaseProductModel.findProductNum(param);
                if (needMerge) {
                    Map<Long,BusinessProductEntity> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (BusinessProductEntity entity : businessProductEntityList){
                        if (productMap.containsKey(entity.getProductId())){
                            BusinessProductEntity businessProductEntity = productMap.get(entity.getProductId());
                            Double preNum = businessProductEntity.getProductNum();
                            Double prePrice = businessProductEntity.getPrice();
                            String preMemo = businessProductEntity.getMemo();
                            Double nowNum = entity.getProductNum();
                            Double nowPrice = entity.getPrice();
                            String nowMemo = entity.getMemo();
                            Double price = (preNum * prePrice + nowNum * nowPrice) / (preNum + nowNum);
                            Double num = preNum + nowNum;
                            String memo = "";
                            if (!StringUtil.isEmpty(nowMemo)){
                                if (StringUtil.isEmpty(preMemo)){
                                    memo = nowMemo;
                                }else {
                                    memo = preMemo + "/" + nowMemo;
                                }
                            }
                            businessProductEntity.setProductNum(num);
                            businessProductEntity.setPrice(price);
                            businessProductEntity.setCost(price);
                            businessProductEntity.setMemo(memo);
                            productMap.put(entity.getProductId(),businessProductEntity);
                        }else {
                            productMap.put(entity.getProductId(),entity);
                        }
                    }
                    businessProductEntityList = new ArrayList<>(productMap.values());
                }
                break;
            case RETURNED_MATERIEL_INSTOCK:
//                BoolQueryBuilder boolQueryBuilder = boolQuery();
//                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE),OutstockTypeEnum.MATERIEL_OUTSTOCK.getCode()));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID),refId));
//                boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
//                List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class, Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
//                if (outstockList.isEmpty()){
//                    return new ArrayList<>();
//                }
//                List<Long> outstockIdList = new ArrayList<>();
//                outstockList.forEach(item -> outstockIdList.add(item.getDataId()));
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
//                param.put("outWarehouseIdIn", outstockIdList);
                param.put("type",OutstockTypeEnum.MATERIEL_OUTSTOCK.getCode());
                param.put("refId", refId);
                param.put("del", 0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = outstockProductModel.findProductNum(param);
                break;
            case TRANSFER_INSTOCK:
//                boolQueryBuilder = boolQuery();
//                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE),OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode()));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID),refId));
//                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
//                outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class,Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
//                if (outstockList.isEmpty()){
//                    return new ArrayList<>();
//                }
//                outstockIdList = new ArrayList<>();
//                outstockList.forEach(item -> outstockIdList.add(item.getDataId()));
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
//                param.put("outWarehouseIdIn", outstockIdList);
                param.put("type", OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode());
                param.put("refId", refId);
                param.put("del", 0);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = outstockProductModel.findProductNum(param);
                for (BusinessProductEntity entity : businessProductEntityList){
                    JSONObject data = entity.getData();
                    if (Objects.nonNull(data)) {
                        entity.setMemo(data.getString(OutstockProductEnum.MEMO.getAttr()));
                        entity.setBatch(data.getString(OutstockProductEnum.BATCH.getAttr()));
                        entity.setProduceDate(data.getLong(OutstockProductEnum.PRODUCE_DATE.getAttr()));
                        entity.setGuaranteePeriod(data.getLong(OutstockProductEnum.GUARANTEE_PERIOD.getAttr()));
                    }
                }
                break;
            case INVENTORY_INSTOCK:
                businessProductEntityList = inventoryProductModel.getInventorySurplusNum(corpid,refId,true);
                for (BusinessProductEntity entity : businessProductEntityList){
                    entity.setGuaranteePeriod(Objects.isNull(entity.getGuaranteePeriod()) ? null : entity.getGuaranteePeriod() / 86400);
                    JSONObject data = entity.getData();
                    if (Objects.nonNull(data)) {
                        entity.setMemo(data.getString(OutstockProductEnum.MEMO.getAttr()));
                        entity.setBatch(data.getString(OutstockProductEnum.BATCH.getAttr()));
                        entity.setProduceDate(data.getLong(OutstockProductEnum.PRODUCE_DATE.getAttr()));
                        entity.setGuaranteePeriod(data.getLong(OutstockProductEnum.GUARANTEE_PERIOD.getAttr()));
                    }
                }
                break;
            case FINSHED_PRODUCT_INSTOCK:
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("productionOrderId",refId);
                param.put("del",0);
                param.put("type",1);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = productionOrderProductModel.findProductNum(param);
                break;
            case RED_CONTRACT_INSTOCK:
                RefundEntityExt entityExt = refundModel.getByKey(refId, corpid);
                Long contractId = entityExt.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr());
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("contractId", contractId);
                param.put("type", ContractProductTypeEnum.REFUND.getCode());
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                businessProductEntityList = contractProductModel.findProductNum(param);
                break;
            default:
                break;
        }
        return businessProductEntityList;
    }

    /**
     * 获取源单产品
     * @param productListDataDTO
     * @return
     * @throws XbbException
     */
    public SourceProductListVO getSourceProductList(ProductListDataDTO productListDataDTO) throws XbbException {
        SourceProductListVO sourceProductListVO = new SourceProductListVO();
        String corpid = productListDataDTO.getCorpid();
        Integer businessType = productListDataDTO.getBusinessType();
        Long refId = productListDataDTO.getRefId();
        Integer refBusinessType = productListDataDTO.getRefType();
        Integer page = productListDataDTO.getPage() == null ? 1 : productListDataDTO.getPage();
        Integer pageSize = productListDataDTO.getPageSize() == null ? 20 : productListDataDTO.getPageSize();
        List<Object> productIdList = new ArrayList<>();
        if (Objects.isNull(productListDataDTO.getConditions())){
            productListDataDTO.setConditions(new ArrayList<>());
        }
        Iterator<ConditionsEntityExt> iterator = productListDataDTO.getConditions().iterator();
        while (iterator.hasNext()) {
            ConditionsEntityExt item = iterator.next();
            if (Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType())) {
                productIdList.addAll(item.getValue());
                iterator.remove();
                break;
            }
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        List<BusinessProductEntity> sourceProductList;
        int refType;
        switch (xbbRefTypeEnum) {
            case REFUND:
                PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.JXC.getAlias(), corpid);
                boolean isOpenJxc = false;
                if (Objects.nonNull(paasAppEntity)) {
                    isOpenJxc = paasAppEntity.getEnable() == 1;
                }
                if (isOpenJxc){
                    productListDataDTO.setSourceFormId(null);
                    productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());
                    BoolQueryBuilder boolQueryBuilder = boolQuery();
                    boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                    boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID),refId));
                    boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE),OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode()));
                    boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
                    List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class,Arrays.asList(FieldTypeEnum.DATAID.getAlias(), FieldTypeEnum.SERIALNO.getAlias()));
                    if (!outstockList.isEmpty()) {
                        Map<Long, String> sheetNoMap = new HashMap<>(outstockList.size());
                        outstockList.forEach(item -> sheetNoMap.put(item.getDataId(), item.getSerialNo()));
                        List<Long> outstockIdList = new ArrayList<>();
                        outstockList.forEach(item -> outstockIdList.add(item.getDataId()));
                        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        param.put("corpid", corpid);
                        param.put("del", 0);
                        param.put("outstockIdIn", outstockIdList);
                        param.put("surplusNum", 0);
                        param.put("start", (page - 1) * pageSize);
                        param.put("pageNum", pageSize);
                        if (CollectionsUtil.isNotEmpty(productIdList)) {
                            param.put("productIdIn", productIdList);
                        }
                        param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                        // 售价是productPrice
                        sourceProductList = outstockProductModel.findProductNum(param);
                        Integer count = outstockProductModel.findProductNumCount(param);
                        PageHelper pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                        sourceProductList.forEach(item -> item.setSheetNo(sheetNoMap.get(item.getRefSheetId())));
                        sourceProductListVO.setBusinessProductList(sourceProductList);
                        sourceProductListVO.setPageHelper(pageHelper);
                    }
                }else {
                    productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
//                    ContractEntityExt contractEntityExt = contractModel.getByKey(refId,corpid);
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("contractId", refId);
                    param.put("noJxcSurplusNum", 0);
                    param.put("start", (page - 1) * pageSize);
                    param.put("pageNum", pageSize);
                    if (CollectionsUtil.isNotEmpty(productIdList)) {
                        param.put("productIdIn", productIdList);
                    }
                    param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                    sourceProductList = contractProductModel.findProductNum(param);
                    Integer count = contractProductModel.findProductNumCount(param);
                    PageHelper pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
//                    sourceProductList.forEach(item -> item.setSheetNo(contractEntityExt.getSerialNo()));
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }
                break;
            case RETURNED_MATERIEL_INSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode());
                productListDataDTO.setSourceFormId(null);
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID),refId));
                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE),OutstockTypeEnum.MATERIEL_OUTSTOCK.getCode()));
                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
                List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class,Arrays.asList(FieldTypeEnum.DATAID.getAlias(), FieldTypeEnum.SERIALNO.getAlias()));
                if (!outstockList.isEmpty()) {
                    Map<Long, String> sheetNoMap = new HashMap<>(outstockList.size());
                    outstockList.forEach(item -> sheetNoMap.put(item.getDataId(), item.getSerialNo()));
                    List<Long> outstockIdList = new ArrayList<>();
                    outstockList.forEach(item -> outstockIdList.add(item.getDataId()));
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("outstockIdIn", outstockIdList);
                    param.put("surplusNum", 0);
                    param.put("start", (page - 1) * pageSize);
                    param.put("pageNum", pageSize);
                    if (CollectionsUtil.isNotEmpty(productIdList)) {
                        param.put("productIdIn", productIdList);
                    }
                    param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                    // 售价是productPrice
                    sourceProductList = outstockProductModel.findProductNum(param);
                    Integer count = outstockProductModel.findProductNumCount(param);
                    PageHelper pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                    sourceProductList.forEach(item -> item.setSheetNo(sheetNoMap.get(item.getRefSheetId())));
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }
                break;
            case RETURNED_PURCHASE:
                productListDataDTO.setSourceFormId(null);
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.PURCHASE_INSTOCK.getCode());
                refType = InstockTypeEnum.PURCHASE_INSTOCK.getCode();
                boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                boolQueryBuilder.filter(termQuery(InstockEnum.getEsAttr4Keyword(InstockEnum.REF_ID),refId));
                boolQueryBuilder.filter(termQuery(InstockEnum.getEsAttr4Keyword(InstockEnum.TYPE),refType));
                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
                List<PaasFormDataEntityExt> instockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_INSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class,Arrays.asList(FieldTypeEnum.DATAID.getAlias(), FieldTypeEnum.SERIALNO.getAlias()));
                if (!instockList.isEmpty()) {
                    Map<Long, String> sheetNoMap = new HashMap<>(instockList.size());
                    instockList.forEach(item -> sheetNoMap.put(item.getDataId(), item.getSerialNo()));
                    List<Long> instockIdList = new ArrayList<>();
                    instockList.forEach(item -> instockIdList.add(item.getDataId()));
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("instockIdIn", instockIdList);
                    param.put("surplusNum", 0);
                    param.put("start", (page - 1) * pageSize);
                    param.put("pageNum", pageSize);
                    if (CollectionsUtil.isNotEmpty(productIdList)) {
                        param.put("productIdIn", productIdList);
                    }
                    param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                    // 单价是cost
                    sourceProductList = instockProductModel.findProductNum(param);
                    Integer count = instockProductModel.findProductNumCount(param);
                    PageHelper pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                    sourceProductList.forEach(item -> item.setSheetNo(sheetNoMap.get(item.getRefSheetId())));
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }
                break;
            case PURCHASE_INSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("purchaseSheetId", refId);
                param.put("surplusNum", 0);
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                param.put("flowStatusIn", Arrays.asList(FlowStatusEnum.IN_APPROVAL.getType(), FlowStatusEnum.APPROVAL_PENDING.getType()));
                param.put("businessType", businessType);
                param.put("formDataId", 0);
                param.put("moduleType", 1);
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                // 单价是productPrice
                sourceProductList = purchaseProductModel.findProductNumIncludeProcess(param);

                if (commonHelp.isOpenWorkFlow(corpid)) {
                    // 获取审批中的采购入库单
                    List<PaasFormDataEntityExt> instockApprovalList = instockModel.findInstockList(corpid, InstockTypeEnum.PURCHASE_INSTOCK.getCode(), refId,
                            Arrays.asList(FlowStatusEnum.IN_APPROVAL.getType(), FlowStatusEnum.APPROVAL_PENDING.getType()), Arrays.asList(FieldTypeEnum.DATAID.getAlias()));
                    List<Long> instockIdIn = new ArrayList<>();
                    instockApprovalList.forEach(item -> instockIdIn.add(item.getDataId()));
                    // 获取审批中的采购入库产品
                    Map<String, Object> paramMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    paramMap.put("corpid", corpid);
                    paramMap.put("refId", refId);
                    paramMap.put("type", InstockTypeEnum.PURCHASE_INSTOCK.getCode());
                    paramMap.put("del", 0);
                    paramMap.put("intoWarehouseIdIn", instockIdIn);
                    List<InstockProductEntity> instockProductEntityList = instockProductModel.findEntitys(paramMap);
                    Map<Long, Double> instockProductNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (InstockProductEntity instockProductEntity : instockProductEntityList) {
                        Double mergeNum = instockProductNumMap.getOrDefault(instockProductEntity.getRefProductId(), 0D);
                        instockProductNumMap.put(instockProductEntity.getRefProductId(), Arith.add(mergeNum, instockProductEntity.getProductNum()));
                    }
                    // 源单产品数量需要减去审批中数量
                    for (BusinessProductEntity businessProductEntity : sourceProductList) {
                        if (instockProductNumMap.containsKey(businessProductEntity.getId())) {
                            Double leftSurplusNum = Arith.sub(businessProductEntity.getSurplusNum(), instockProductNumMap.get(businessProductEntity.getId()));
                            businessProductEntity.setSurplusNum(leftSurplusNum);
                        }
                    }
                }

                Integer count = purchaseProductModel.findProductNumCountIncludeProcess(param);
                PageHelper pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            case PRODUCTION_INSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.PRODUCTION_ORDER.getCode());
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("productionOrderId", refId);
                param.put("surplusNum", 0);
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                param.put("type", 1);
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                // 单价是productPrice
                sourceProductList = productionOrderProductModel.findProductNum(param);
                count = productionOrderProductModel.findProductNumCount(param);
                pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            case REFUND_INSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.REFUND.getCode());
                RefundEntityExt refundEntityExt = refundModel.getByKey(refId,corpid);
                Long contractId = refundEntityExt.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr());
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("contractId", contractId);
                param.put("refundSurplusNum", 0);
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                param.put("type", ContractProductTypeEnum.REFUND.getCode());
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                // 退货单价是price
                count = contractProductModel.findProductNumCount(param);
                sourceProductList = contractProductModel.findProductNum(param);
                // 退货退款入库取销售出库成本
                boolean needMerge = true;
                for (BusinessProductEntity contractProductEntity : sourceProductList) {
                    if (Objects.nonNull(contractProductEntity.getRefProductId()) && !Objects.equals(contractProductEntity.getRefProductId(), 0)) {
                        needMerge = false;
                        break;
                    }
                }
                param.clear();
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("refId", refundEntityExt.getData().getLong(RefundEnum.CONTRACT_ID.getAttr()));
                param.put("type", OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode());
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                List<OutstockProductEntity> outstockProductEntityList = outstockProductModel.findEntitys(param);
                Map<Long, Double> totalCostMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<Long, Double> totalNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<Object, Double> costMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                HashSet<Long> dataIdList = new HashSet<>();
                if (needMerge) {
                    for (OutstockProductEntity outstockProductEntity : outstockProductEntityList) {
                        Long productId = outstockProductEntity.getProductId();
                        dataIdList.add(productId);
                        Double extraCost = Arith.mul(outstockProductEntity.getCost(), outstockProductEntity.getProductNum());
                        if (totalCostMap.containsKey(productId)) {
                            Double totalCost = totalCostMap.get(productId);
                            totalCostMap.put(productId, Arith.add(totalCost, extraCost));
                        } else {
                            totalCostMap.put(productId, extraCost);
                        }
                        if (totalNumMap.containsKey(productId)) {
                            Double totalNum = totalNumMap.get(productId);
                            totalNumMap.put(productId, Arith.add(totalNum, outstockProductEntity.getProductNum()));
                        } else {
                            totalNumMap.put(productId, outstockProductEntity.getProductNum());
                        }
                    }
                }else {
                    for (OutstockProductEntity outstockProductEntity : outstockProductEntityList) {
                        Long productId = outstockProductEntity.getProductId();
                        dataIdList.add(productId);
                    }
                }

                for (Long productId : dataIdList) {
                    if (needMerge) {
                        if (totalCostMap.containsKey(productId) && totalNumMap.containsKey(productId) && !Objects.equals(totalNumMap.get(productId),0)) {
                            costMap.put(productId, Arith.div(totalCostMap.get(productId), totalNumMap.get(productId)));
                        }
                    } else {
                        for (BusinessProductEntity refundProduct : sourceProductList) {
                            if (Objects.equals(productId, refundProduct.getProductId())) {
                                Long refProductId = refundProduct.getRefProductId();
                                for (OutstockProductEntity outstockProductEntity : outstockProductEntityList) {
                                    if (Objects.equals(outstockProductEntity.getId(), refProductId)) {
                                        costMap.put(productId + "_" + refundProduct.getId(), outstockProductEntity.getCost());
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                for (BusinessProductEntity businessProductEntity : sourceProductList) {
                    businessProductEntity.setCost(costMap.getOrDefault(businessProductEntity.getProductId(), 0D));
                    if (Objects.nonNull(businessProductEntity.getRefProductId())) {
                        businessProductEntity.setCost(costMap.getOrDefault(businessProductEntity.getProductId() + "_" + businessProductEntity.getId(), 0D));
                    }
                    businessProductEntity.setSurplusNum(businessProductEntity.getRefundSurplusNum());
                }
                pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            case CONTRACT_OUTSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.CONTRACT.getCode());

                // 查询是否可以超发出库
                // 查询是否可以超发出库
                ContractEntityExt contractEntity = contractModel.getByKey(refId, corpid);
                boolean overOutstock  = false;
                if(Objects.nonNull(contractEntity)){
                    FormConfigEntity overOutstockConfig = formConfigModel.getEntityByFormId(corpid, contractEntity.getFormId(), FormConfigEnum.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD.getConfig());
                    overOutstock = Objects.nonNull(overOutstockConfig) && Objects.equals(overOutstockConfig.getConfigValue(), "1");
                }
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("contractId", refId);
                // 如果不可以超发出库，需要校验出库数 - 仓库出库数 > 0
                if (!overOutstock) {
                    param.put("surplusNum", 0);
                }
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                param.put("type", XbbRefTypeEnum.CONTRACT.getCode());
                param.put("flowStatusIn", Arrays.asList(FlowStatusEnum.IN_APPROVAL.getType(), FlowStatusEnum.APPROVAL_PENDING.getType()));
                param.put("businessType", businessType);
                param.put("formDataId", 0);
                param.put("moduleType", 1);
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                // 售价是price
                sourceProductList = contractProductModel.findProductNumIncludeProcess(param);
                count = contractProductModel.findProductNumCountIncludeProcess(param);
                pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            case RETURNED_PURCHASE_OUTSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("returnPurchaseId", refId);
                param.put("surplusNum", 0);
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                // 退货单价是productPrice
                sourceProductList = returnedPurchaseProductModel.findProductNum(param);
                count = returnedPurchaseProductModel.findProductNumCount(param);
                pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            case WORK_ORDER_OUTSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("workOrderId", refId);
                param.put("surplusNum", 0);
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                param.put("flowStatusIn", Arrays.asList(FlowStatusEnum.IN_APPROVAL.getType(), FlowStatusEnum.APPROVAL_PENDING.getType()));
                param.put("businessType", businessType);
                param.put("formDataId", 0);
                param.put("moduleType", 1);
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                sourceProductList = workOrderProductModel.findProductNumIncludeProcess(param);
                count = workOrderProductModel.findProductNumCountIncludeProcess(param);
                pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            case OTHER_INSTOCK:
                if (Objects.equals(refBusinessType, InstockTypeEnum.TRANSFER_INSTOCK.getCode())) {
                    productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.OTHER_OUTSTOCK.getCode());
                    param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("refId", refId);
                    param.put("type", OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode());
                    param.put("start", (page - 1) * pageSize);
                    param.put("pageNum", pageSize);
                    if (CollectionsUtil.isNotEmpty(productIdList)) {
                        param.put("productIdIn", productIdList);
                    }
                    param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                    sourceProductList = outstockProductModel.findProductNum(param);
                    List<InstockProductEntity> instockProductEntityList = instockProductModel.getUpStreamProduct(corpid, refBusinessType, refId);
                    Map<String,Double> businessNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (InstockProductEntity entity : instockProductEntityList){
                        Double num = entity.getProductNum();
                        String key = entity.getProductId() + "_" + entity.getRefProductId();
                        businessNumMap.put(key,Arith.add(businessNumMap.getOrDefault(key,0D), num));
                    }
                    Iterator<BusinessProductEntity> businessIterator = sourceProductList.iterator();
                    TransferEntityExt transferModelByKey = transferModel.getByKey(refId, corpid);
                    while (businessIterator.hasNext()){
                        BusinessProductEntity entity = businessIterator.next();
                        Long productId = entity.getProductId();
                        Long id = entity.getId();
                        String key = productId + "_" + id;
                        Double num = entity.getProductNum();
                        if (businessNumMap.containsKey(key)){
                           entity.setSurplusNum(Arith.sub(num, businessNumMap.get(key)));
                            if (entity.getSurplusNum() <= 0){
                                businessIterator.remove();
                            }
                        }
                        entity.setWarehouseId(transferModelByKey.getData().getLong(TransferEnum.INTO_WAREHOUSE_ID.getAttr()));
                    }
                    count = outstockProductModel.findProductNumCount(param);
                    pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }else if (Objects.equals(refBusinessType, InstockTypeEnum.INVENTORY_INSTOCK.getCode())){
                    productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.OTHER_INSTOCK.getCode());
                    param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("inventoryId", refId);
                    param.put("start", (page - 1) * pageSize);
                    param.put("pageNum", pageSize);
                    if (CollectionsUtil.isNotEmpty(productIdList)) {
                        param.put("productIdIn", productIdList);
                    }
                    param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                    sourceProductList = inventoryProductModel.getInventorySurplusNum(corpid, refId, true);
                    count = sourceProductList.size();
                    pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }
                break;
            case OTHER_OUTSTOCK:
                if (Objects.equals(refBusinessType, OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode())) {
                    productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.OTHER_OUTSTOCK.getCode());
                    param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("transferId", refId);
                    param.put("surplusNum", 0);
                    param.put("start", (page - 1) * pageSize);
                    param.put("pageNum", pageSize);
                    if (CollectionsUtil.isNotEmpty(productIdList)) {
                        param.put("productIdIn", productIdList);
                    }
                    param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                    sourceProductList = transferProductModel.findProductNum(param);
                    count = transferProductModel.findProductNumCount(param);
                    pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }else if (Objects.equals(refBusinessType, OutstockTypeEnum.INVENTORY_OUTSTOCK.getCode())){
                    productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.OTHER_OUTSTOCK.getCode());
                    sourceProductList = inventoryProductModel.getInventorySurplusNum(corpid, refId, false);
                    count = sourceProductList.size();
                    pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                    sourceProductListVO.setBusinessProductList(sourceProductList);
                    sourceProductListVO.setPageHelper(pageHelper);
                }
                break;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                productListDataDTO.setSourceBusinessType(XbbRefTypeEnum.PRODUCTION_ORDER.getCode());
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("productionOrderId", refId);
                param.put("start", (page - 1) * pageSize);
                param.put("pageNum", pageSize);
                param.put("type", 2);
                if (CollectionsUtil.isNotEmpty(productIdList)) {
                    param.put("productIdIn", productIdList);
                }
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                // 单价是productPrice
                sourceProductList = productionOrderProductModel.findProductNum(param);
                count = productionOrderProductModel.findProductNumCount(param);
                pageHelper = new PageHelper(page, pageSize).setRowsCount(count);
                sourceProductListVO.setBusinessProductList(sourceProductList);
                sourceProductListVO.setPageHelper(pageHelper);
                break;
            default:
                break;
        }

        if (Objects.isNull(sourceProductListVO.getBusinessProductList())){
            sourceProductListVO.setBusinessProductList(new ArrayList<>());
            PageHelper pageHelper = new PageHelper(page, pageSize).setRowsCount(0);
            sourceProductListVO.setPageHelper(pageHelper);
        }
        return sourceProductListVO;
    }

    /**
     * 退货退款关联单据产品检索
     * @param corpid 公司id
     * @param contractId 关联合同id
     * @param isOpenJxc 是否开启jxc
     * @return
     * @throws XbbException
     */
    public List<BusinessProductEntity> searchContractUnRefund(String corpid, Long contractId, boolean isOpenJxc) throws XbbException {
        //该合同下已存在的退货退款
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery(RefundEnum.getEsAttr4Keyword(RefundEnum.CONTRACT_ID),contractId));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
        List<PaasFormDataEntityExt> refundList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_REFUND,boolQueryBuilder,PaasFormDataEntityExt.class,Collections.singletonList(RefundEnum.getAttrConnectData(RefundEnum.RED_CONTRACT_ID)));
        Map<String,Double> refundMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 退货退款需要合同的单价，还需要加权平均
        // Map<String,Double> priceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        boolean needMerge = false;
        if (!refundList.isEmpty()) {
            List<Long> refundIdList = new ArrayList<>();
            refundList.forEach(item -> refundIdList.add(item.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr())));
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("contractIdIn", refundIdList);
            param.put("type", ContractProductTypeEnum.REFUND.getCode());
            param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
            List<BusinessProductEntity> refundProductList = contractProductModel.findProductNum(param);
            for (BusinessProductEntity entity : refundProductList) {
                if (Objects.isNull(entity.getRefProductId())) {
                    needMerge = true;
                    break;
                }
            }
            for (BusinessProductEntity entity : refundProductList){
                String key;
                if (needMerge) {
                    key = entity.getProductId().toString();
                } else {
                    key = entity.getProductId() + "_" + entity.getRefProductId();
                }
                Double num  = refundMap.getOrDefault(key,0D);
                //Double originNum = num;
                num += Math.abs(entity.getProductNum());
                /*if (priceMap.containsKey(key)) {
                    Double originPrice = priceMap.get(key);
                    Double totalPrice = Arith.mul(originNum, originPrice);
                    Double price = entity.getPrice() == null ? 0D : entity.getPrice();
                    Double averagePrice =  Arith.div(Arith.add(totalPrice, Arith.mul(entity.getProductNum(), price)), num);
                    priceMap.put(key,averagePrice);
                } else {
                    Double price = entity.getPrice() == null ? 0D : entity.getPrice();
                    priceMap.put(key,price);
                }*/
                refundMap.put(key,num);
            }
        }
        List<BusinessProductEntity> businessProductEntitys = new ArrayList<>();
        //可以被退的最大产品

        List<BusinessProductEntity> businessProductEntityList = getRefundRelyBusinessProduct(corpid,contractId,isOpenJxc);
        Iterator<BusinessProductEntity> iterator = businessProductEntityList.iterator();
        while (iterator.hasNext()) {
            BusinessProductEntity entity = iterator.next();
            Double num = entity.getProductNum();
            String key;
            if (needMerge) {
                key = entity.getProductId().toString();
            } else {
                key = entity.getProductId() + "_" + entity.getId();
            }
            if (refundMap.containsKey(key)) {
                if (num > refundMap.get(key)) {
                    entity.setProductNum(num - refundMap.get(key));
                } else {
                    iterator.remove();
                }
            }
        }
        return businessProductEntitys;
    }


    /**
     * 查询合同未退货产品
     * @param corpid
     * @param contractId
     * @param isOpenJxc
     * @return
     * @throws XbbException
     */
    private List<BusinessProductEntity> getRefundRelyBusinessProduct(String corpid, Long contractId, boolean isOpenJxc) throws XbbException {
        List<BusinessProductEntity> businessProductEntityList = new ArrayList<>();
        if (isOpenJxc){
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
            boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID),contractId));
            boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE),OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode()));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
            List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class, Arrays.asList(FieldTypeEnum.DATAID.getAlias(),FieldTypeEnum.SERIALNO.getAlias()));
            if (!outstockList.isEmpty()){
                List<Long> outstockIdList = new ArrayList<>();
                Map<Long, String> outstockMap = new HashMap<>(outstockList.size());
                outstockList.forEach(item -> {
                    outstockIdList.add(item.getDataId());
                    outstockMap.put(item.getDataId(), item.getSerialNo());
                });
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("del",0);
                param.put("outstockIdIn",outstockIdList);
                param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
                List<OutstockProductEntity> outstockProductEntityList = outstockProductModel.findEntitys(param);
                for (OutstockProductEntity outstockProductEntity : outstockProductEntityList) {
                    BusinessProductEntity businessProductEntity = new BusinessProductEntity();
                    BeanUtil.copyProperties(outstockProductEntity, businessProductEntity);
                    businessProductEntity.setRefSheetId(outstockProductEntity.getOutWarehouseId());
                    businessProductEntity.setSheetNo(outstockMap.get(outstockProductEntity.getOutWarehouseId()));
                    businessProductEntityList.add(businessProductEntity);
                }
            }
        }else {
            ContractEntityExt contractEntityExt = contractModel.getByKey(contractId, corpid);
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid",corpid);
            param.put("del",0);
            param.put("contractId",contractId);
            param.put("type",ContractProductTypeEnum.CONTNRACT.getCode());
            param.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
            List<ContractProductEntity> contractProductEntities = contractProductModel.findEntitys(param);
            for (ContractProductEntity contractProductEntity : contractProductEntities) {
                BusinessProductEntity businessProductEntity = new BusinessProductEntity();
                BeanUtil.copyProperties(contractProductEntity, businessProductEntity);
                businessProductEntity.setRefSheetId(contractProductEntity.getContractId());
                businessProductEntity.setSheetNo(contractEntityExt.getSerialNo());
                businessProductEntityList.add(businessProductEntity);
            }
        }
        return businessProductEntityList;
    }

    /**
     * 判断数据是否为老数据
     * @param corpid
     * @param refId
     * @param businessType 业务类型
     * @return
     * @throws XbbException
     */
    public boolean isOldData(String corpid, Long refId, Integer businessType, Integer refType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        boolean isOld = false;
        if(Objects.isNull(refId) || Objects.equals(refId,0L)){
            return true;
        }
        switch (xbbRefTypeEnum) {
            case REFUND:
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                boolQueryBuilder.filter(termQuery(RefundEnum.getEsAttr4Keyword(RefundEnum.CONTRACT_ID),refId));
                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
                boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
                List<PaasFormDataEntityExt> refundList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_REFUND,boolQueryBuilder,PaasFormDataEntityExt.class,Collections.singletonList(RefundEnum.getAttrConnectData(RefundEnum.RED_CONTRACT_ID)));
                if (CollectionsUtil.isNotEmpty(refundList)) {
                    List<Long> refundIdList = new ArrayList<>();
                    refundList.forEach(item -> refundIdList.add(item.getData().getLong(RefundEnum.RED_CONTRACT_ID.getAttr())));
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("contractIdIn", refundIdList);
                    param.put("type", ContractProductTypeEnum.REFUND.getCode());
                    param.put("refProductIdIsNull",1);
                    return contractProductModel.getEntitysCount(param) > 0;
//                    List<BusinessProductEntity> refundProductList = contractProductModel.findProductNum(param);
//                    for (BusinessProductEntity entity : refundProductList) {
//                        if (Objects.isNull(entity.getRefProductId())) {
//                            isOld = true;
//                            break;
//                        }
//                    }
                }
                break;
            case RETURNED_PURCHASE:
                boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                boolQueryBuilder.filter(termQuery(ReturnedPurchaseEnum.getEsAttr4Keyword(ReturnedPurchaseEnum.PURCHASE_SHEET_ID),refId));
                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
                List<PaasFormDataEntityExt> returnPurchaseList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE,boolQueryBuilder,PaasFormDataEntityExt.class,Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
                if (!returnPurchaseList.isEmpty()) {
                    List<Long> returnPurchaseIdList = new ArrayList<>();
                    returnPurchaseList.forEach(item -> returnPurchaseIdList.add(item.getDataId()));
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    param.put("returnPurchaseIdIn", returnPurchaseIdList);
                    List<BusinessProductEntity> returnPuchaseProductList = returnedPurchaseProductModel.findProductNum(param);
                    for (BusinessProductEntity entity : returnPuchaseProductList) {
                        if (Objects.isNull(entity.getRefProductId())) {
                            isOld = true;
                            break;
                        }
                    }
                }
                break;
            case RETURNED_MATERIEL_INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case PRODUCTION_INSTOCK:
//                boolQueryBuilder = boolQuery();
//                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
//                boolQueryBuilder.filter(termQuery(InstockEnum.getEsAttr4Keyword(InstockEnum.REF_ID),refId));
//                boolQueryBuilder.filter(termQuery(InstockEnum.getEsAttr4Keyword(InstockEnum.TYPE),InstockTypeEnum.getByStockBusinessType(businessType).getCode()));
//                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
//                List<PaasFormDataEntityExt> instockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_INSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class,Arrays.asList(FieldTypeEnum.DATAID.getAlias()));
//                if (!instockList.isEmpty()){
//                    List<Long> instockIdList = new ArrayList<>();
//                    instockList.forEach(item -> {
//                        instockIdList.add(item.getDataId());
//                    });
                    Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid",corpid);
                    param.put("type",InstockTypeEnum.getByStockBusinessType(businessType).getCode());
                    param.put("refId",refId);
                    param.put("del",0);
                    List<InstockProductEntity> instockProductEntityList = instockProductModel.findEntitys(param);
                    for (InstockProductEntity entity : instockProductEntityList) {
                        if (Objects.isNull(entity.getRefProductId())) {
                            isOld = true;
                            break;
                        }
                    }
//                }
                break;
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
//                boolQueryBuilder = boolQuery();
//                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID),refId));
//                boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE),OutstockTypeEnum.getByStockBusinessType(businessType).getCode()));
//                boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
//                List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder,PaasFormDataEntityExt.class,Arrays.asList(FieldTypeEnum.DATAID.getAlias()));
//                if (!outstockList.isEmpty()){
//                    List<Long> outstockIdList = new ArrayList<>();
//                    outstockList.forEach(item -> {
//                        outstockIdList.add(item.getDataId());
//                    });
                    param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid",corpid);
                    param.put("type",OutstockTypeEnum.getByStockBusinessType(businessType).getCode());
                    param.put("refId",refId);
                    param.put("del",0);
                    List<OutstockProductEntity> outstockProductEntityList = outstockProductModel.findEntitys(param);
                    for (OutstockProductEntity entity : outstockProductEntityList) {
                        if (Objects.isNull(entity.getRefProductId())) {
                            isOld = true;
                            break;
                        }
                    }
//                }
                break;
            case OTHER_INSTOCK:
                if (Objects.equals(refType, InstockTypeEnum.TRANSFER_INSTOCK.getCode()) || Objects.equals(refType, InstockTypeEnum.INVENTORY_INSTOCK.getCode())) {
                    isOld = false;
                }else {
                    isOld = true;
                }
                break;
            case OTHER_OUTSTOCK:
                if (Objects.equals(refType, OutstockTypeEnum.TRANSFER_OUTSTOCK.getCode()) || Objects.equals(refType, OutstockTypeEnum.INVENTORY_OUTSTOCK.getCode())) {
                    isOld = false;
                }else {
                    isOld = true;
                }
                break;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                isOld = false;
                break;
            default:
                break;
        }
        return isOld;
    }

    /**
     * 源单数据封装
     * @param jsonObject
     * @param sourceData
     * @param businessProductEntity
     * @param businessType
     * @param corpid
     * @param stockField
     * @throws XbbException
     */
    public JSONObject putProductSourceData(JSONObject jsonObject, JSONObject sourceData, BusinessProductEntity businessProductEntity, Integer businessType, String corpid, ProductFieldPojo stockField) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        JSONObject sourceInfo = new JSONObject();
        if (Objects.nonNull(businessProductEntity.getGuaranteePeriod())) {
            Long guaranteePeriod = businessProductEntity.getGuaranteePeriod();
            Long guaranteePeriodDay = guaranteePeriod / 86400;
            businessProductEntity.setGuaranteePeriod(guaranteePeriodDay);
        }
        if (Objects.equals(businessProductEntity.getProduceDate(),0L)) {
            businessProductEntity.setProduceDate(null);
        }
        JSONObject data = businessProductEntity.getData();
        sourceInfo.put(BusinessConstant.RELATION_PRODUCT_DATA, businessProductEntity.getData());
        boolean enableSerial = Objects.nonNull(jsonObject) && Objects.equals(jsonObject.getInteger(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr()), 1);
        boolean hasChangePrice = false;
        if (Objects.nonNull(businessProductEntity.getBusinessUnit())) {
            if (!enableSerial && Arith.round(Arith.div(businessProductEntity.getSurplusNum(), businessProductEntity.getRate()), stockField.getAccuracy()) != BasicConstant.ZERO_DOUBLE) {
                businessProductEntity.setSurplusNum(Arith.div(businessProductEntity.getSurplusNum(), businessProductEntity.getRate(), stockField.getAccuracy()));
                businessProductEntity.setProductUnit(businessProductEntity.getBusinessUnit().toString());
                JSONObject priceData = businessProductEntity.getPriceData();
                if (Objects.nonNull(priceData) && !priceData.isEmpty()) {
                    businessProductEntity.setPrice(priceData.getDouble(SelectProductEnum.SELLING_PRICE.getAttr()));
                    businessProductEntity.setHistoricalPrice(priceData.getDouble(SelectProductEnum.PRICE.getAttr()));
                    if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INSTOCK.getCode())) {
                        businessProductEntity.setCost(priceData.getDouble(SelectProductEnum.PRICE.getAttr()));
                    } else {
                        businessProductEntity.setCost(priceData.getDouble(SelectProductEnum.COST.getAttr()));
                    }
                    hasChangePrice = true;
                }
            } else {
                businessProductEntity.setBusinessUnit(Long.parseLong(businessProductEntity.getProductUnit()));
            }
        }
        switch (xbbRefTypeEnum) {
            case REFUND:
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_SOURCE_DOC.getAttr(), businessProductEntity.getSheetNo());
                    jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), businessProductEntity.getPrice());
                    jsonObject.put(SelectProductEnum.SOURCE_BATCH.getAttr(), businessProductEntity.getBatch());
                    jsonObject.put(SelectProductEnum.SOURCE_GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                    jsonObject.put(SelectProductEnum.SOURCE_PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                }
                sourceInfo.put(RefundProductEnum.COST.getAttr(),businessProductEntity.getCost());
                sourceInfo.put(RefundProductEnum.PRICE.getAttr(),businessProductEntity.getPrice());
                sourceInfo.put(RefundProductEnum.SOURCE_DOC.getAttr(),businessProductEntity.getSheetNo());
                JSONObject refundBatch = new JSONObject();
                refundBatch.put("text", businessProductEntity.getBatch());
                refundBatch.put("value", businessProductEntity.getBatch());
                sourceInfo.put(RefundProductEnum.BATCH.getAttr(), refundBatch);
                sourceInfo.put(RefundProductEnum.PRODUCE_DATE.getAttr(),businessProductEntity.getProduceDate());
                sourceInfo.put(RefundProductEnum.GUARANTEE_PERIOD.getAttr(),businessProductEntity.getGuaranteePeriod());
                break;
            case RETURNED_PURCHASE:
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_SOURCE_DOC.getAttr(), businessProductEntity.getSheetNo());
                    jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), businessProductEntity.getCost());
//                    JSONObject jsonObject1 = new JSONObject();
//                    jsonObject1.put("text",businessProductEntity.getBatch());
//                    jsonObject1.put("value",businessProductEntity.getBatch());
                    jsonObject.put(SelectProductEnum.SOURCE_BATCH.getAttr(), businessProductEntity.getBatch());
                    jsonObject.put(SelectProductEnum.SOURCE_GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                    jsonObject.put(SelectProductEnum.SOURCE_PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                }
                JSONObject returnBatch = new JSONObject();
                returnBatch.put("text", businessProductEntity.getBatch());
                returnBatch.put("value", businessProductEntity.getBatch());
                sourceInfo.put(ReturnPurchaseProductEnum.BATCH.getAttr(), returnBatch);
                sourceInfo.put(ReturnPurchaseProductEnum.PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                sourceInfo.put(ReturnPurchaseProductEnum.GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                sourceInfo.put(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr(),businessProductEntity.getCost());
                sourceInfo.put(ReturnPurchaseProductEnum.SOURCE_DOC.getAttr(),businessProductEntity.getSheetNo());
                if (Objects.nonNull(data)) {
                    JSONArray warehouse = new JSONArray();
                    JSONObject warehouseObject = new JSONObject();
                    warehouseObject.put("id", data.get(SelectProductEnum.WAREHOUSE.getAttr()));
                    warehouseObject.put("name", data.get("warehouseName"));
                    warehouse.add(warehouseObject);
                    sourceInfo.put(ReturnPurchaseProductEnum.WAREHOUSE.getAttr(), warehouse);
                }
                break;
            case RETURNED_MATERIEL_INSTOCK:
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_SOURCE_DOC.getAttr(), businessProductEntity.getSheetNo());
                    jsonObject.put(SelectProductEnum.SOURCE_BATCH.getAttr(), businessProductEntity.getBatch());
                    jsonObject.put(SelectProductEnum.SOURCE_GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                    jsonObject.put(SelectProductEnum.SOURCE_PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                    jsonObject.put(ReturnedMaterielInstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                    sourceInfo.put(ReturnedMaterielInstockProductEnum.STOCK.getAttr(), jsonObject.get(ProductEnum.STOCK.getAttr()));
                }
                sourceInfo.put(ReturnedMaterielInstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                // 生产退料单的成本使用领料出库的成本覆盖
                if (Objects.nonNull(sourceData)){
                    sourceData.put(ReturnedMaterielInstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                }
                sourceInfo.put(ReturnPurchaseProductEnum.SOURCE_DOC.getAttr(),businessProductEntity.getSheetNo());
                sourceInfo.put(ReturnedMaterielInstockProductEnum.BATCH.getAttr(), businessProductEntity.getBatch());
                sourceInfo.put(ReturnedMaterielInstockProductEnum.GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                sourceInfo.put(ReturnedMaterielInstockProductEnum.PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                break;
            case PURCHASE_INSTOCK:
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), businessProductEntity.getCost());
                    sourceInfo.put(PurchaseInstockProductEnum.STOCK.getAttr(), jsonObject.get(ProductEnum.STOCK.getAttr()));
                }
                sourceInfo.put(PurchaseInstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                break;
            case REFUND_INSTOCK:
                if (hasChangePrice) {
                    businessProductEntity.setPrice(businessProductEntity.getPriceData().getDouble(SelectProductEnum.PRICE.getAttr()));
                }
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), businessProductEntity.getPrice());
                    if (Objects.nonNull(data)) {
                        jsonObject.put(SelectProductEnum.SOURCE_BATCH.getAttr(), data.getString(SelectProductEnum.BATCH.getAttr()));
                        jsonObject.put(SelectProductEnum.SOURCE_GUARANTEE_PERIOD.getAttr(), data.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr()));
                        jsonObject.put(SelectProductEnum.SOURCE_PRODUCE_DATE.getAttr(), data.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()));
                        sourceInfo.put(SelectProductEnum.BATCH.getAttr(), data.getString(SelectProductEnum.BATCH.getAttr()));
                        sourceInfo.put(SelectProductEnum.GUARANTEE_PERIOD.getAttr(), data.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr()));
                        sourceInfo.put(SelectProductEnum.PRODUCE_DATE.getAttr(), data.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()));
                    }
                    sourceInfo.put(RefundInstockProductEnum.STOCK.getAttr(), jsonObject.get(ProductEnum.STOCK.getAttr()));
                }
                sourceInfo.put(RefundInstockProductEnum.PRICE.getAttr(), businessProductEntity.getPrice());
                sourceInfo.put(RefundInstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                break;
            case CONTRACT_OUTSTOCK:
                // 销售相关
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), businessProductEntity.getPrice());
                    sourceInfo.put(ContractOutstockProductEnum.STOCK.getAttr(), jsonObject.get(ProductEnum.STOCK.getAttr()));
                }
                sourceInfo.put(ContractOutstockProductEnum.SELLING_PRICE.getAttr(),businessProductEntity.getPrice());
                sourceInfo.put(ContractOutstockProductEnum.PRICE.getAttr(),businessProductEntity.getHistoricalPrice());
                sourceInfo.put(ContractOutstockProductEnum.DISCOUNT.getAttr(),businessProductEntity.getDiscount());
                sourceInfo.put(ContractOutstockProductEnum.SUBTOTAL.getAttr(),Arith.mul(businessProductEntity.getPrice(),businessProductEntity.getProductNum()));
                sourceInfo.put(ContractOutstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                break;
            case RETURNED_PURCHASE_OUTSTOCK:
                if (Objects.nonNull(jsonObject)) {
                    jsonObject.put(SelectProductEnum.SOURCE_PRICE.getAttr(), businessProductEntity.getCost());
                    if (Objects.nonNull(data)) {
                        jsonObject.put(SelectProductEnum.SOURCE_BATCH.getAttr(), data.getString(SelectProductEnum.BATCH.getAttr()));
                        jsonObject.put(SelectProductEnum.SOURCE_GUARANTEE_PERIOD.getAttr(), data.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr()));
                        jsonObject.put(SelectProductEnum.SOURCE_PRODUCE_DATE.getAttr(), data.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()));
                    }
                    sourceInfo.put(ReturnedPurchaseOutstockProductEnum.STOCK.getAttr(), jsonObject.get(ProductEnum.STOCK.getAttr()));
                }
                sourceInfo.put(ReturnedPurchaseOutstockProductEnum.COST.getAttr(),businessProductEntity.getCost());
                sourceInfo.put(ReturnedPurchaseOutstockProductEnum.UNIT.getAttr(),businessProductEntity.getProductUnit());
                break;
            case OTHER_INSTOCK:
                sourceInfo.put(SelectProductEnum.NUM.getAttr(), businessProductEntity.getProductNum());
                sourceInfo.put(InstockProductEnum.COST.getAttr(), businessProductEntity.getCost());
                sourceInfo.put(InstockProductEnum.UNIT.getAttr(), businessProductEntity.getProductUnit());
                sourceInfo.put(InstockProductEnum.MEMO.getAttr(), businessProductEntity.getMemo());
                sourceInfo.put(InstockProductEnum.BATCH.getAttr(), businessProductEntity.getBatch());
                sourceInfo.put(InstockProductEnum.PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                sourceInfo.put(InstockProductEnum.GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                break;
            case PRODUCTION_INSTOCK:
                sourceInfo.put(SelectProductEnum.NUM.getAttr(), businessProductEntity.getProductNum());
                break;
            case OTHER_OUTSTOCK:
                sourceInfo.put(SelectProductEnum.NUM.getAttr(), businessProductEntity.getProductNum());
                sourceInfo.put(OutstockProductEnum.COST.getAttr(), businessProductEntity.getCost());
                sourceInfo.put(OutstockProductEnum.UNIT.getAttr(), businessProductEntity.getProductUnit());
                sourceInfo.put(OutstockProductEnum.MEMO.getAttr(), businessProductEntity.getMemo());
                if (StringUtil.isNotEmpty(businessProductEntity.getBatch())) {
                    JSONObject batch = new JSONObject();
                    batch.put("text",businessProductEntity.getBatch());
                    batch.put("value",businessProductEntity.getBatch());
                    sourceInfo.put(OutstockProductEnum.BATCH.getAttr(), batch);
                }
                sourceInfo.put(OutstockProductEnum.PRODUCE_DATE.getAttr(), businessProductEntity.getProduceDate());
                sourceInfo.put(OutstockProductEnum.GUARANTEE_PERIOD.getAttr(), businessProductEntity.getGuaranteePeriod());
                break;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                if (Objects.nonNull(businessProductEntity.getSurplusNum()) && businessProductEntity.getSurplusNum() <= 0){
                    businessProductEntity.setSurplusNum(0D);
                }
                break;
            case WORK_ORDER_OUTSTOCK:
                if (Objects.nonNull(jsonObject)){
                    sourceInfo.put(SelectProductEnum.PRICE.getAttr(), jsonObject.getDoubleValue(ProductEnum.PRICE.getAttr()));
                }
                break;
            default:
                break;
        }

        JSONObject unitObject = saasFormHelp.formatUnit(corpid,businessProductEntity.getProductUnit());
        sourceInfo.put(SelectProductEnum.NUM.getAttr(), businessProductEntity.getSurplusNum());
        sourceInfo.put(SelectProductEnum.MEMO.getAttr(), businessProductEntity.getMemo());
        sourceInfo.put(SelectProductEnum.UNIT.getAttr(), unitObject);
        if (Objects.nonNull(jsonObject) && Objects.nonNull(sourceData)) {
            // 备注
            sourceData.put(ProductEnum.UNIT.getAttr(),unitObject);
            jsonObject.put(ProductEnum.UNIT.getAttr(),sourceData.get(ProductEnum.UNIT.getAttr()));
            jsonObject.put(BusinessConstant.SOURCE_INFO, sourceInfo);
            sourceData.put(BusinessConstant.SOURCE_INFO, sourceInfo);
        }
        return sourceInfo;
    }

    /**
     * 获取单位组map，每个组的选项
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Map<Long, List<UnitItemPoJo>> getGroupItemsMap(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        return multiItems.stream().collect(Collectors.toMap(MultiUnitItemPoJo::getValue, MultiUnitItemPoJo::getItemDataPoJoList, (a, b) -> b, () -> new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY)));
    }

    /**
     * 获取业务单位key，value map，业务单位回显
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Map<String, String> getBusinessUnitMap(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<UnitItemPoJo> multiItemDataPoJoList = productFieldPojo.getMultiItemDataPoJoList();
        List<ItemPoJo> singleItems = productFieldPojo.getSingleItems();
        singleItems.removeIf(itemPoJo -> StringUtil.isEmpty(Objects.toString(itemPoJo.getValue(),"")));
        List<ItemPoJo> businessItemsPojo = new ArrayList<>(singleItems);
        try {
            BeanUtil.copyPropertiesList(multiItemDataPoJoList, businessItemsPojo, ItemPoJo.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        Map<String, String> unitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        businessItemsPojo.forEach(item-> unitMap.put(String.valueOf(item.getValue()),item.getText()));
        return unitMap;
    }


    /**
     * 获取产品单位选项
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public List<ItemPoJo> getProductBaseItems(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<ItemPoJo> unitItems = new ArrayList<>(productFieldPojo.getSingleItems());
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        List<ItemPoJo> multiItemsPojo = new ArrayList<>();
        for (MultiUnitItemPoJo multiUnitItemPoJo : multiItems) {
            ItemPoJo itemPoJo = new ItemPoJo();
            itemPoJo.setValue(multiUnitItemPoJo.getValue());
            itemPoJo.setText(multiUnitItemPoJo.getBaseName());
            multiItemsPojo.add(itemPoJo);
        }
        unitItems.addAll(multiItemsPojo);
        return unitItems;
    }

    /**
     * 获取产品单位选项
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Map<String, String> getProductUnitItemMap(String corpid) throws XbbException{
        List<ItemPoJo> productItems = getProductBaseItems(corpid);
        return productItems.stream().collect(Collectors.toMap(itemPoJo -> Objects.toString(itemPoJo.getValue(), ""), ItemPoJo::getText));
    }

    /**
     * 获取业务单位选项
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public List<ItemPoJo> getBusinessUnitItems(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<UnitItemPoJo> multiItemDataPoJoList = productFieldPojo.getMultiItemDataPoJoList();
        List<ItemPoJo> businessItemsPojo = new ArrayList<>(productFieldPojo.getSingleItems());
        try {
            BeanUtil.copyPropertiesList(multiItemDataPoJoList, businessItemsPojo, ItemPoJo.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return businessItemsPojo;
    }

    /**
     * 获取单位组map，每个组的选项
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Map<Long, MultiUnitItemPoJo> getGroupBaseUnitMap(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        Map<Long, MultiUnitItemPoJo> groupMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        multiItems.forEach(item-> groupMap.put(item.getValue(), item));
        return groupMap;
    }

    /**
     * 获取单位组map，每个组的选项key为String类型
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Map<String, MultiUnitItemPoJo> getGroupBaseUnitStringMap(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        Map<String, MultiUnitItemPoJo> groupMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        multiItems.forEach(item-> groupMap.put(Objects.toString(item.getValue(), ""), item));
        return groupMap;
    }
    /**
     * 获取单位组
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    public MultiUnitItemPoJo getGroupMessage(String corpid, Long groupId) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        Map<Long, MultiUnitItemPoJo> groupMap = multiItems.stream().collect(Collectors.toMap(MultiUnitItemPoJo::getValue, item -> item, (a, b) -> b, () -> new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY)));
        return groupMap.get(groupId);
    }

    /**
     * 根据产品单位value 拿基本单位value
     *
     * @param corpid 公司ID
     * @return Map<String, String>
     * @throws XbbException
     */
    public Map<String, String> getBaseValue(String corpid) throws XbbException{
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        Map<String, String> baseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        multiItems.forEach(item->baseMap.put(Objects.toString(item.getValue(),""), Objects.toString(item.getBaseValue(), "")));
        productFieldPojo.getSingleItems().forEach(itemPoJo -> baseMap.put(Objects.toString(itemPoJo.getValue(), ""), Objects.toString(itemPoJo.getValue(), "")));
        return baseMap;
    }

    /**
     * 合同、报价单、机会保存价目表售价校验
     *
     * @param corpid       公司ID
     * @param formId       表单ID
     * @param data         数据
     * @param attr         关联产品attr
     * @param businessType 业务类型
     */
    public void preCheckSavePrice(String corpid, Long formId, JSONObject data, String attr, Integer businessType) throws XbbException {
        JSONArray jsonArray = data.getJSONArray(attr);
        List<Long> productIdIn = new ArrayList<>();
        Map<Long, Boolean> multiUnitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> productIdSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject subData = jsonArray.getJSONObject(i);
            long productId = subData.getLongValue(SelectProductEnum.PRODUCT.getAttr());
            productIdIn.add(productId);
            multiUnitMap.put(productId, subData.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr()) == 1);
            productIdSet.add(productId);
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        Long distributorId;
        switch (xbbRefTypeEnum) {
            case CONTRACT:
                distributorId = data.getJSONArray(ContractEnum.LINK_CUSTOMER.getAttr()).getJSONObject(0).getLongValue(StringConstant.SAAS_LINK_BUSINESS_ID);
                break;
            case SALES_OPPORTUNITY:
                distributorId = data.getJSONArray(SalesOpportunityEnum.CUSTOMER_NAME.getAttr()).getJSONObject(0).getLongValue(StringConstant.SAAS_LINK_BUSINESS_ID);
                break;
            case QUOTATION:
                distributorId = data.getJSONArray(QuotationEnum.CUSTOMER_ID.getAttr()).getJSONObject(0).getLongValue(StringConstant.SAAS_LINK_BUSINESS_ID);
                break;
            default:
                distributorId = 0L;
                break;
        }

        Map<String, PriceProductSetEntity> priceMap = productModel.getPriceMap(corpid, distributorId, formId, productIdIn, multiUnitMap);
        if (MapUtils.isEmpty(priceMap)) {
            return;
        }
        //获取价目表可用范围
        List<Long> priceIdList = new ArrayList<>();
        priceMap.forEach((k,v) ->{
            priceIdList.add(v.getPriceId());
        });
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("del",DelEnum.NORMAL.getDel());
        param.put("idIn",priceIdList);
        List<PriceSetEntity> priceSetEntityList = priceSetModel.findEntitys(param);
        Map<Long, List<Integer>> scopeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        priceSetEntityList.forEach(item ->{
            List<Integer> scopeList = new ArrayList<>();
            String scope = item.getScope().substring(item.getScope().indexOf("[") + 1, item.getScope().lastIndexOf("]"));
            String [] scopeString = scope.split(",");
            for(int i=0; i<scopeString.length; i++){
                scopeList.add(Integer.valueOf(scopeString[i]));
            }
            scopeMap.put(item.getId(), scopeList);
        });
        // 产品信息
        List<PaasFormDataEntityExt> productEntityList = productModel.getProductListById(productIdSet, corpid, DelEnum.NORMAL);
        formDataHelp.setChildSpecification(productEntityList, corpid);
        Map<Long, PaasFormDataEntityExt> productMap = new HashMap<>(productEntityList.size());
        productEntityList.forEach(item -> productMap.put(item.getDataId(), item));
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject subData = jsonArray.getJSONObject(i);
            Double sellingPrice = subData.getDouble(SelectProductEnum.SELLING_PRICE.getAttr());
            long productId = subData.getLongValue(SelectProductEnum.PRODUCT.getAttr());
            String key = String.valueOf(productId);
            if (multiUnitMap.get(productId)) {
                key = productId + SymbolConstant.UNDERLINE + subData.getString(SelectProductEnum.UNIT.getAttr());
            }
            PriceProductSetEntity priceProductSetEntity = priceMap.get(key);
            if (priceProductSetEntity == null) {
                continue;
            }
            //判断价目表的可用范围
            if (scopeMap.containsKey(priceProductSetEntity.getPriceId())){
                List<Integer> scopeList = scopeMap.get(priceProductSetEntity.getPriceId());
                Boolean scope = PriceSetScopeEnum.getBusinessTypeByType(businessType, scopeList);
                if (!scope){
                    continue;
                }
            }
            // 校验售价是否超过价目表售价浮动上下限
            PaasFormDataEntityExt product = productMap.get(productId);
            if (Objects.nonNull(priceProductSetEntity.getPriceFloor()) && Arith.compare(sellingPrice, priceProductSetEntity.getPriceFloor()) < 0) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.SELLING_PRICE_LESS_THAN), product.getData().getString(ProductEnum.NAME.getAttr()), product.getData().getString(ProductEnum.SPECIFICATION.getAttr()), priceProductSetEntity.getPriceFloor()));
            }
            if (Objects.nonNull(priceProductSetEntity.getPriceCap()) && Arith.compare(sellingPrice, priceProductSetEntity.getPriceCap()) > 0) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.SELLING_PRICE_MORE_THAN), product.getData().getString(ProductEnum.NAME.getAttr()), product.getData().getString(ProductEnum.SPECIFICATION.getAttr()), priceProductSetEntity.getPriceCap()));
            }
            if ((Objects.isNull(priceProductSetEntity.getPriceFloor()) && Objects.isNull(priceProductSetEntity.getPriceCap())) && Objects.nonNull(priceProductSetEntity.getSellingPrice()) && !Objects.equals(sellingPrice, priceProductSetEntity.getSellingPrice())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.NO_USE_PRICE), product.getData().getString(ProductEnum.NAME.getAttr()), product.getData().getString(ProductEnum.SPECIFICATION.getAttr())));
            }
        }
    }
}
